package com.zhoug.zxing.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.zhoug.zxing.activity.CaptureActivity2;

import androidx.activity.ComponentActivity;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultCaller;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.ActivityResultRegistry;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;

/**
 * @Author 35574
 * @Date 2020/6/28
 * @Description
 */
public class ZxingHelper {
    private static final String TAG = ">>>ZxingHelper";
    private Callback callback;
    @Deprecated
    private Activity activity;
    @Deprecated
    private Fragment fragment;
    private boolean mSearchEnable = false;//是否启用右边的搜索按钮
    private boolean mChooseImageEnable = true;//是否允许选择相册中的图片识别二维码
    /**
     * 扫描框范围矩形背景是否启用
     * true:设置背景为R.drawable.zxing_scan_rect_bg
     * false:设置背景@android:color/transparent
     */
    private boolean mScanRectBgEnable = false;

    private String mSearchActivityClassName;//搜索页面Activity全名
    private String mSearchHintText;//搜索页面搜索框提示
    private String mTitle;//扫一扫页面标题
    private String mSaoMaDescription;//扫一扫页面的描述
    private ActivityResultLauncher<Intent> mLauncher;
    private static IPermissionRequest iPermissionRequest;

    public static ZxingHelper registerForActivityResult(@NonNull Fragment fragment) {
        return registerForActivityResult(fragment, fragment.getViewLifecycleOwner());
    }

    public static ZxingHelper registerForActivityResult(@NonNull ComponentActivity activity) {
        return registerForActivityResult(activity, activity);
    }

    public static ZxingHelper registerForActivityResult(@NonNull ActivityResultCaller caller, @NonNull LifecycleOwner lifecycleOwner) {
        return new ZxingHelper(caller, lifecycleOwner);
    }

    public static void setPermissionRequest(IPermissionRequest iPermissionRequest){
        ZxingHelper.iPermissionRequest=iPermissionRequest;
    }

    public static IPermissionRequest getPermissionRequest() {
        return iPermissionRequest;
    }

    @Deprecated
    public ZxingHelper(Activity activity) {
        this.activity = activity;
    }

    @Deprecated
    public ZxingHelper(Fragment fragment) {
        this.fragment = fragment;
    }

    private ZxingHelper(@NonNull ActivityResultCaller caller, LifecycleOwner lifecycleOwner) {
        mLauncher = caller.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result != null && result.getResultCode() == Activity.RESULT_OK) {
                    invokeResult(result.getData());
                }
            }
        });
        if (lifecycleOwner != null) {
            lifecycleOwner.getLifecycle().addObserver(new DefaultLifecycleObserver() {
                @Override
                public void onDestroy(@NonNull LifecycleOwner owner) {
                    unregister();
                }
            });
        }
    }

    public void unregister() {
        if (mLauncher != null) {
            mLauncher.unregister();
        }
    }


    public ZxingHelper setSearchHintText(String searchHintText) {
        this.mSearchHintText = searchHintText;
        return this;
    }

    public ZxingHelper setTitle(String title) {
        this.mTitle = title;
        return this;
    }

    public ZxingHelper setSearchEnable(boolean searchEnable) {
        this.mSearchEnable = searchEnable;
        return this;
    }

    public ZxingHelper setChooseImageEnable(boolean chooseImageEnable) {
        this.mChooseImageEnable = chooseImageEnable;
        return this;
    }

    /**
     * see {@link #setSearchActivityClassName(String)}
     *
     * @param searchActivityClassName
     * @return
     */
    @Deprecated
    public ZxingHelper setSearchActivityName(String searchActivityClassName) {
        return setSearchActivityClassName(searchActivityClassName);
    }

    /**
     * 搜索页面Activity全名
     * 需要setResult返回数据 ,输入存在 resultData字段中
     * eg:
     * Intent result = new Intent();
     * result.putExtra("resultData", "哈哈哈哈");
     * setResult(RESULT_OK, result);
     * finish();
     *
     * @param searchActivityClassName
     * @return
     */
    public ZxingHelper setSearchActivityClassName(String searchActivityClassName) {
        this.mSearchActivityClassName = searchActivityClassName;
        return this;
    }

    public ZxingHelper setSaoMaDescription(String description) {
        this.mSaoMaDescription = description;
        return this;
    }

    public ZxingHelper setScanRectBgEnable(boolean scanRectBgEnable) {
        this.mScanRectBgEnable = scanRectBgEnable;
        return this;
    }

    public void start(@NonNull Context context) {
        if (mLauncher != null) {
            Intent intent = new Intent(context, CaptureActivity2.class);
            initParams(intent);
            mLauncher.launch(intent);
        } else {
            start();
        }
    }


    @Deprecated
    public void start() {
        if (fragment != null) {
            Intent intent = new Intent(fragment.getContext(), CaptureActivity2.class);
            initParams(intent);
            fragment.startActivityForResult(intent, 1001);
        } else if (activity != null) {
            Intent intent = new Intent(activity, CaptureActivity2.class);
            initParams(intent);
            activity.startActivityForResult(intent, 1001);
        } else {
            Log.e(TAG, "fragmentc and activity all null");
        }
    }

    private void initParams(Intent intent) {
        intent.putExtra(CaptureActivity2.PARAM_SEARCH_ENABLE, mSearchEnable);
        intent.putExtra(CaptureActivity2.PARAM_CHOOSE_IMAGE_ENABLE, mChooseImageEnable);
        intent.putExtra(CaptureActivity2.PARAM_SEARCH_ACTIVITY_NAME, mSearchActivityClassName);
        intent.putExtra(CaptureActivity2.PARAM_SEARCH_HINT_TEXT, mSearchHintText);
        intent.putExtra(CaptureActivity2.PARAM_TITLE, mTitle);
        intent.putExtra(CaptureActivity2.PARAM_DESCRIPTION, mSaoMaDescription);
        intent.putExtra(CaptureActivity2.PARAM_SCAN_RECT_BG_ENABLE, mScanRectBgEnable);
    }

    /**
     * 执行结果回掉
     *
     * @param data
     */
    private void invokeResult(Intent data) {
        //处理扫描结果（在界面上显示）
        if (null != data) {
            Bundle bundle = data.getExtras();
            if (bundle == null) {
                if (callback instanceof Callback2) {
                    ((Callback2) callback).onResult(Callback.CODE_FAIL, null, null, "解码错误");
                } else {
                    callback.result(Callback.CODE_FAIL, "解码错误");
                }
            } else {
                String result = bundle.getString("result");
                if (callback instanceof Callback2) {
                    ((Callback2) callback).onResult(Callback.CODE_SUCCESS, result, bundle.getByteArray("byteArray"), null);
                } else {
                    callback.result(Callback.CODE_SUCCESS, result);

                }
            }
        } else {
            if (callback instanceof Callback2) {
                ((Callback2) callback).onResult(Callback.CODE_FAIL, null, null, "扫码失败");
            } else {
                callback.result(Callback.CODE_FAIL, "扫码失败");
            }
        }

    }

    @Deprecated
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (mLauncher != null) return;
        if (resultCode == Activity.RESULT_OK && requestCode == 1001) {
            invokeResult(data);
        }
    }


    public Callback getCallback() {
        return callback;
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public interface Callback {
        int CODE_SUCCESS = 2;
        int CODE_FAIL = 1;

        /**
         * @param code {@link #CODE_FAIL,#CODE_SUCCESS}
         * @param msg
         */
        void result(int code, String msg);

    }

    public interface Callback2 extends Callback {

        /**
         * @param code {@link #CODE_FAIL,#CODE_SUCCESS}
         * @param msg
         */
        @Deprecated
        @Override
        void result(int code, String msg);

        /**
         * @param code      {@link #CODE_FAIL,#CODE_SUCCESS}
         * @param text      文本数据
         * @param byteArray 字节数据
         * @param error     错误信息
         */
        void onResult(int code, String text, byte[] byteArray, String error);

    }
}
